View Javadoc
1   package org.apache.maven.surefire.testng;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.util.Collection;
24  import java.util.List;
25  import java.util.Map;
26  
27  import org.apache.maven.surefire.booter.Command;
28  import org.apache.maven.surefire.booter.MasterProcessListener;
29  import org.apache.maven.surefire.booter.MasterProcessReader;
30  import org.apache.maven.surefire.cli.CommandLineOption;
31  import org.apache.maven.surefire.providerapi.AbstractProvider;
32  import org.apache.maven.surefire.providerapi.ProviderParameters;
33  import org.apache.maven.surefire.report.ReporterConfiguration;
34  import org.apache.maven.surefire.report.ReporterFactory;
35  import org.apache.maven.surefire.suite.RunResult;
36  import org.apache.maven.surefire.testng.utils.FailFastEventsSingleton;
37  import org.apache.maven.surefire.testset.TestListResolver;
38  import org.apache.maven.surefire.testset.TestRequest;
39  import org.apache.maven.surefire.testset.TestSetFailedException;
40  import org.apache.maven.surefire.util.RunOrderCalculator;
41  import org.apache.maven.surefire.util.ScanResult;
42  import org.apache.maven.surefire.util.TestsToRun;
43  
44  /**
45   * @author Kristian Rosenvold
46   * @noinspection UnusedDeclaration
47   */
48  public class TestNGProvider
49      extends AbstractProvider
50  {
51      private final Map<String, String> providerProperties;
52  
53      private final ReporterConfiguration reporterConfiguration;
54  
55      private final ClassLoader testClassLoader;
56  
57      private final ScanResult scanResult;
58  
59      private final TestRequest testRequest;
60  
61      private final ProviderParameters providerParameters;
62  
63      private final RunOrderCalculator runOrderCalculator;
64  
65      private final List<CommandLineOption> mainCliOptions;
66  
67      private final MasterProcessReader commandsReader;
68  
69      private TestsToRun testsToRun;
70  
71      public TestNGProvider( ProviderParameters booterParameters )
72      {
73          // don't start a thread in MasterProcessReader while we are in in-plugin process
74          commandsReader = booterParameters.isInsideFork()
75              ? MasterProcessReader.getReader().setShutdown( booterParameters.getShutdown() )
76              : null;
77          providerParameters = booterParameters;
78          testClassLoader = booterParameters.getTestClassLoader();
79          runOrderCalculator = booterParameters.getRunOrderCalculator();
80          providerProperties = booterParameters.getProviderProperties();
81          testRequest = booterParameters.getTestRequest();
82          reporterConfiguration = booterParameters.getReporterConfiguration();
83          scanResult = booterParameters.getScanResult();
84          mainCliOptions = booterParameters.getMainCliOptions();
85      }
86  
87      public RunResult invoke( Object forkTestSet )
88          throws TestSetFailedException
89      {
90          try
91          {
92              if ( isFailFast() && commandsReader != null )
93              {
94                  registerPleaseStopListener();
95              }
96  
97              if ( commandsReader != null )
98              {
99                  commandsReader.awaitStarted();
100             }
101 
102             final ReporterFactory reporterFactory = providerParameters.getReporterFactory();
103 
104             if ( isTestNGXmlTestSuite( testRequest ) )
105             {
106                 TestNGXmlTestSuite testNGXmlTestSuite = newXmlSuite();
107                 testNGXmlTestSuite.locateTestSets( testClassLoader );
108                 if ( forkTestSet != null && testRequest == null )
109                 {
110                     testNGXmlTestSuite.execute( (String) forkTestSet, reporterFactory );
111                 }
112                 else
113                 {
114                     testNGXmlTestSuite.execute( reporterFactory );
115                 }
116             }
117             else
118             {
119                 if ( testsToRun == null )
120                 {
121                     if ( forkTestSet instanceof TestsToRun )
122                     {
123                         testsToRun = (TestsToRun) forkTestSet;
124                     }
125                     else if ( forkTestSet instanceof Class )
126                     {
127                         testsToRun = TestsToRun.fromClass( (Class<?>) forkTestSet );
128                     }
129                     else
130                     {
131                         testsToRun = scanClassPath();
132                     }
133                 }
134 
135                 if ( commandsReader != null )
136                 {
137                     commandsReader.addShutdownListener( new MasterProcessListener()
138                     {
139                         public void update( Command command )
140                         {
141                             testsToRun.markTestSetFinished();
142                         }
143                     } );
144                 }
145                 TestNGDirectoryTestSuite suite = newDirectorySuite();
146                 suite.execute( testsToRun, reporterFactory );
147             }
148 
149             return reporterFactory.close();
150         }
151         finally
152         {
153             closeCommandsReader();
154         }
155     }
156 
157     boolean isTestNGXmlTestSuite( TestRequest testSuiteDefinition )
158     {
159         Collection<File> suiteXmlFiles = testSuiteDefinition.getSuiteXmlFiles();
160         return suiteXmlFiles != null && !suiteXmlFiles.isEmpty() && !hasSpecificTests();
161     }
162 
163     private boolean isFailFast()
164     {
165         return providerParameters.getSkipAfterFailureCount() > 0;
166     }
167 
168     private int getSkipAfterFailureCount()
169     {
170         return isFailFast() ? providerParameters.getSkipAfterFailureCount() : 0;
171     }
172 
173     private void closeCommandsReader()
174     {
175         if ( commandsReader != null )
176         {
177             commandsReader.stop();
178         }
179     }
180 
181     private MasterProcessListener registerPleaseStopListener()
182     {
183         MasterProcessListener listener = new MasterProcessListener()
184         {
185             public void update( Command command )
186             {
187                 FailFastEventsSingleton.getInstance().setSkipOnNextTest();
188             }
189         };
190         commandsReader.addSkipNextListener( listener );
191         return listener;
192     }
193 
194     private TestNGDirectoryTestSuite newDirectorySuite()
195     {
196         return new TestNGDirectoryTestSuite( testRequest.getTestSourceDirectory().toString(), providerProperties,
197                                              reporterConfiguration.getReportsDirectory(), createMethodFilter(),
198                                              runOrderCalculator, scanResult, mainCliOptions,
199                                              getSkipAfterFailureCount() );
200     }
201 
202     private TestNGXmlTestSuite newXmlSuite()
203     {
204         return new TestNGXmlTestSuite( testRequest.getSuiteXmlFiles(),
205                                        testRequest.getTestSourceDirectory().toString(),
206                                        providerProperties,
207                                        reporterConfiguration.getReportsDirectory(), getSkipAfterFailureCount() );
208     }
209 
210     @SuppressWarnings( "unchecked" )
211     public Iterable<Class<?>> getSuites()
212     {
213         if ( isTestNGXmlTestSuite( testRequest ) )
214         {
215             try
216             {
217                 return newXmlSuite().locateTestSets( testClassLoader ).keySet();
218             }
219             catch ( TestSetFailedException e )
220             {
221                 throw new RuntimeException( e );
222             }
223         }
224         else
225         {
226             testsToRun = scanClassPath();
227             return testsToRun;
228         }
229     }
230 
231     private TestsToRun scanClassPath()
232     {
233         final TestsToRun scanned = scanResult.applyFilter( null, testClassLoader );
234         return runOrderCalculator.orderTestClasses( scanned );
235     }
236 
237     private boolean hasSpecificTests()
238     {
239         TestListResolver tests = testRequest.getTestListResolver();
240         return tests != null && !tests.isEmpty();
241     }
242 
243     private TestListResolver createMethodFilter()
244     {
245         TestListResolver tests = testRequest.getTestListResolver();
246         return tests == null ? null : tests.createMethodFilters();
247     }
248 }